import sys
from PyQt5.QtWidgets import (
    QApplication, QMainWindow, QLabel, QPushButton, QVBoxLayout, QHBoxLayout,
    QWidget, QComboBox, QDoubleSpinBox, QTableWidget, QTableWidgetItem,
    QGridLayout, QCheckBox, QScrollArea, QFrame, QHeaderView, QMessageBox
)
from PyQt5.QtGui import QPixmap
from PyQt5.QtCore import Qt, QTimer

from components.image_processor import ImageProcessor
from components.process_thread import ProcessThread


class MilitaryDetectionSystem(QMainWindow):
    def __init__(self):
        super().__init__()
        self.image_processor = ImageProcessor()
        self.image_processor.image_processed.connect(self.update_detection_result)
        self.image_processor.processing_finished.connect(self.processing_completed)
        self.image_processor.error_occurred.connect(self.handle_error)
        
        # 创建处理线程
        self.process_thread = None
        
        self.initUI()

    def initUI(self):
        self.setWindowTitle("复杂场景下的军事目标检测平台")
        self.setGeometry(100, 100, 1280, 800)
        self.setStyleSheet("background-color: #2B3E50; color: white;")

        # 主布局
        main_widget = QWidget()
        self.setCentralWidget(main_widget)
        main_layout = QVBoxLayout(main_widget)
        main_layout.setSpacing(10)
        main_layout.setContentsMargins(20, 20, 20, 20)

        # 1. 标题
        title_label = QLabel("🔹 复杂场景下的军事目标检测平台 🔹")
        title_label.setAlignment(Qt.AlignCenter)
        title_label.setStyleSheet("""
            font-size: 34px;
            font-weight: bold;
            color: #FFD700;
            text-shadow: 2px 2px 4px black;
            padding: 10px;
        """)
        main_layout.addWidget(title_label)

        # 2. 控制面板
        control_layout = QHBoxLayout()
        control_layout.setSpacing(10)

        def create_control_frame(label_text, widget):
            frame = QFrame()
            frame.setStyleSheet(
                "font-size:20px; background-color: #1C2833; border: 2px solid #34495E; border-radius: 10px; padding: 8px;")
            layout = QHBoxLayout(frame)
            layout.addWidget(QLabel(label_text))
            layout.addWidget(widget)
            return frame

        self.total_targets_label = QLabel("")
        self.time_used_label = QLabel("")
        self.target_selection = QComboBox()

        control_layout.addWidget(create_control_frame("总目标数:", self.total_targets_label))
        control_layout.addWidget(create_control_frame("用时:", self.time_used_label))
        control_layout.addWidget(create_control_frame("目标选择:", self.target_selection))
        main_layout.addLayout(control_layout)

        # 右侧控制面板
        right_control = QFrame()
        right_control.setStyleSheet("""
            QFrame {
                font-size:20px;
                background-color: #1C2833;
                border: 2px solid #34495E;
                border-radius: 10px;
                padding: 10px;
            }
        """)

        right_layout = QHBoxLayout(right_control)

        confidence_label = QLabel("置信度阈值: 0.25")
        confidence_label.setStyleSheet("background-color: #34495E; padding: 5px;")
        right_layout.addWidget(confidence_label)

        # 显示交并比阈值
        iou_label = QLabel("交并比阈值: 0.70")
        iou_label.setStyleSheet("background-color: #34495E; padding: 5px;")
        right_layout.addWidget(iou_label)

        control_layout.addWidget(right_control)
        main_layout.addLayout(control_layout)

        # 3. 中间内容区域
        content_layout = QHBoxLayout()

        # 左侧图片区域
        self.image_label = QLabel()
        self.image_label.setFixedSize(800, 500)
        self.image_label.setStyleSheet("""
            background-color: #1C2833;
            border: 2px solid #34495E;
            border-radius: 10px;
        """)
        self.image_label.setAlignment(Qt.AlignCenter)

        content_layout.addWidget(self.image_label)

        # 右侧信息区域
        right_info = QVBoxLayout()

        # 显示标签复选框
        self.show_labels_checkbox = QCheckBox("显示标签名称与置信度")
        self.show_labels_checkbox.setStyleSheet("font-size: 22px;")
        right_info.addWidget(self.show_labels_checkbox)

        # 检测结果框
        detection_frame = QFrame()
        detection_frame.setStyleSheet("""
            QFrame {
                background-color: #1C2833;
                border: 2px solid #34495E;
                border-radius: 10px;
                padding: 15px;
            }
        """)
        detection_layout = QVBoxLayout(detection_frame)
        self.detection_name = QLabel("")
        self.detection_name.setStyleSheet("font-size: 22px; font-weight: bold;")
        detection_layout.addWidget(self.detection_name)

        self.detection_conf = QLabel("")
        self.detection_conf.setStyleSheet("font-size: 22px;")
        detection_layout.addWidget(self.detection_conf)

        right_info.addWidget(detection_frame)

        # 目标位置框
        position_frame = QFrame()
        position_frame.setStyleSheet("""
            QFrame {
                font-size:20px;
                background-color: #1C2833;
                border: 2px solid #34495E;
                border-radius: 10px;
                padding: 15px;
            }
        """)
        position_layout = QGridLayout(position_frame)

        self.coord_labels = {}
        coords = [('xmin', 0, 0), ('ymin', 0, 1), ('xmax', 1, 0), ('ymax', 1, 1)]
        for coord, row, col in coords:
            label = QLabel("")
            label.setStyleSheet("font-size: 24px;")
            position_layout.addWidget(label, row, col)
            self.coord_labels[coord] = label

        right_info.addWidget(position_frame)
        content_layout.addLayout(right_info)
        main_layout.addLayout(content_layout)

        # 4. 底部区域
        bottom_layout = QHBoxLayout()

        # 表格区域
        self.details_table = QTableWidget()
        self.details_table.setColumnCount(5)
        self.details_table.setHorizontalHeaderLabels(['件路径', '目标编号', '类别', '置信度', '坐标位置'])
        
        # 设置表格样式
        self.details_table.setStyleSheet("""
            QTableWidget {
                background-color: #1C2833;
                border: 2px solid #34495E;
                border-radius: 10px;
                gridline-color: #34495E;
            }
            QHeaderView::section {
                background-color: #2C3E50;
                padding: 5px;
                border: 1px solid #34495E;
            }
            QTableCornerButton::section {
                background-color: #2C3E50;
                border: 2px solid #34495E;
            }
            QScrollBar:vertical {
                background: #1C2833;
                width: 12px;
                margin: 0px;
            }
            QScrollBar::handle:vertical {
                background: #34495E;
                min-height: 20px;
                border-radius: 6px;
            }
            QScrollBar::add-line:vertical, QScrollBar::sub-line:vertical {
                height: 0px;
            }
        """)
        
        # 设置表格属性
        self.details_table.setCornerButtonEnabled(False)
        self.details_table.verticalHeader().setVisible(False)  # 隐藏行号
        self.details_table.setSelectionBehavior(QTableWidget.SelectRows)  # 整行选择
        self.details_table.setSelectionMode(QTableWidget.SingleSelection)  # 单行选择
        self.details_table.setEditTriggers(QTableWidget.NoEditTriggers)  # 不可编辑
        
        # 设置列宽
        self.details_table.setColumnWidth(0, 270)
        self.details_table.setColumnWidth(1, 100)
        self.details_table.setColumnWidth(2, 130)
        self.details_table.setColumnWidth(3, 80)
        self.details_table.setColumnWidth(4, 450)
        
        # 设置表格高度
        self.details_table.setFixedHeight(300)
        
        # 添加表格点击事件处理
        self.details_table.cellClicked.connect(self.show_table_row_info)
        
        # 直接将表格添加到布局中，不使用 QScrollArea
        bottom_layout.addWidget(self.details_table, stretch=7)

        # 右侧按钮区域
        button_frame = QFrame()
        button_frame.setStyleSheet("""
            QFrame {
                background-color: #1C2833;
                border: 2px solid #34495E;
                border-radius: 10px;
                padding: 10px;
            }
        """)
        button_layout = QVBoxLayout(button_frame)
        button_layout.setSpacing(10)

        buttons = ["自动处理", "处理图片", "❌ 退出系统"]

        for text in buttons:
            btn = QPushButton(text)
            btn.setStyleSheet("""
                QPushButton {
                    background-color: #34495E;
                    border: 1px solid #2C3E50;
                    border-radius: 5px;
                    padding: 8px;
                    color: white;
                    font-weight: bold;
                }
                QPushButton:hover {
                    background-color: #2C3E50;
                }
            """)
            if text == "处理图片":
                btn.clicked.connect(self.process_image)
            elif text == "自动处理":
                btn.clicked.connect(self.auto_process)
            else:
                btn.clicked.connect(self.close)
            button_layout.addWidget(btn)

        bottom_layout.addWidget(button_frame, stretch=2)
        main_layout.addLayout(bottom_layout)

        # 初始化时不填充数据
        self.details_table.setRowCount(0)
        
        # 清除其他标签的初始值
        self.total_targets_label.setText("")
        self.time_used_label.setText("")
        self.detection_name.setText("")
        self.detection_conf.setText("")
        for coord in self.coord_labels.values():
            coord.setText("")

    def process_image(self):
        """处理图片按钮点击事件"""
        self.image_processor.process_next_image()

    def update_detection_result(self, result):
        """更新检测结果到界面"""
        try:
            # 更新图片
            pixmap = QPixmap(result['image_path'])
            if pixmap.isNull():
                print(f"无法加载图片: {result['image_path']}")
                return
                
            self.image_label.setPixmap(
                pixmap.scaled(self.image_label.size(), 
                             Qt.KeepAspectRatio, 
                             Qt.SmoothTransformation)
            )

            # 更新基本信息
            self.total_targets_label.setText(str(result['total_targets']))
            self.time_used_label.setText(result['time_used'])
            
            # 更新目标选择下拉框
            self.target_selection.clear()
            target_types = list(set(d['type'] for d in result['detections']))
            self.target_selection.addItems(target_types)
            
            # 更新表格（累积数据）
            self.append_to_detection_table(result)
            
        except Exception as e:
            print(f"更新界面时出错: {str(e)}")
            self.handle_error(str(e))

    def append_to_detection_table(self, result):
        """向表格添加新的检测结果"""
        current_row_count = self.details_table.rowCount()
        new_rows = len(result['detections'])
        
        # 先添加新行
        self.details_table.setRowCount(current_row_count + new_rows)
        
        # 将现有数据下移
        for row in range(current_row_count - 1, -1, -1):
            for col in range(5):
                item = self.details_table.takeItem(row, col)
                if item:
                    self.details_table.setItem(row + new_rows, col, item)
        
        # 在顶部插入新数据
        for i in range(new_rows):
            detection = result['detections'][i]
            # 格式化坐标值，添加属性名
            coords = detection['coords'].split(',')
            formatted_coords = f"xmin:{coords[0]},ymin:{coords[1]},xmax:{coords[2]},ymax:{coords[3]}"
            
            self.details_table.setItem(i, 0, QTableWidgetItem(result['image_path']))
            self.details_table.setItem(i, 1, QTableWidgetItem(detection['id']))
            self.details_table.setItem(i, 2, QTableWidgetItem(detection['type']))
            self.details_table.setItem(i, 3, QTableWidgetItem(detection['confidence']))
            self.details_table.setItem(i, 4, QTableWidgetItem(formatted_coords))

    def processing_completed(self):
        """处理完成的回调"""
        # 这个方法可以删除，或者留着做其他用途
        pass

    def populate_fake_data(self):
        """填充表格假数据"""
        fake_data = get_fake_data()

        # 设置表格行数为实际数据的数量
        self.details_table.setRowCount(len(fake_data))

        # 填充数据
        for row, data in enumerate(fake_data):
            self.details_table.setItem(row, 0, QTableWidgetItem(data['path']))
            self.details_table.setItem(row, 1, QTableWidgetItem(data['id']))
            self.details_table.setItem(row, 2, QTableWidgetItem(data['type']))
            self.details_table.setItem(row, 3, QTableWidgetItem(data['conf']))
            self.details_table.setItem(row, 4, QTableWidgetItem(data['coords']))

    def show_table_row_info(self, row, column):
        """当表格行被点击时更新右侧信息"""
        # 提取点击行的数据
        file_path = self.details_table.item(row, 0).text()
        target_id = self.details_table.item(row, 1).text()
        target_type = self.details_table.item(row, 2).text()
        confidence = self.details_table.item(row, 3).text()
        coords = self.details_table.item(row, 4).text()

        # 更新右侧信息框
        self.detection_name.setText(f"检测名称：{target_type}")
        self.detection_conf.setText(f"置信度：{confidence}")
        
        # 解析带属性名的坐标值
        coord_dict = {}
        for coord in coords.split(','):
            key, value = coord.split(':')
            coord_dict[key] = value
        
        # 更新坐标信息
        self.coord_labels['xmin'].setText(f"xmin: {coord_dict['xmin']}")
        self.coord_labels['ymin'].setText(f"ymin: {coord_dict['ymin']}")
        self.coord_labels['xmax'].setText(f"xmax: {coord_dict['xmax']}")
        self.coord_labels['ymax'].setText(f"ymax: {coord_dict['ymax']}")

    def handle_error(self, error_msg):
        """处理错误"""
        QMessageBox.warning(self, "错误", f"处理过程中出现错误：{error_msg}")

    def auto_process(self):
        """自动处理所有图片"""
        try:
            # 重置处理器
            self.image_processor.reset()
            
            # 如果线程已存在，先停止它
            if self.process_thread and self.process_thread.isRunning():
                self.process_thread.stop()
                self.process_thread.wait()
            
            # 创建新的处理线程
            self.process_thread = ProcessThread()
            self.process_thread.process_signal.connect(self.process_next)
            self.process_thread.finished_signal.connect(self.on_thread_finished)  # 连接完成信号
            self.process_thread.start()
            
        except Exception as e:
            print(f"启动自动处理时出错: {str(e)}")
            self.handle_error(str(e))

    def process_next(self):
        """处理下一张图片"""
        try:
            if not self.image_processor.process_next_image():
                # 如果处理完成，停止线程
                if self.process_thread:
                    self.process_thread.stop()
        except Exception as e:
            print(f"处理下一张图片时出错: {str(e)}")
            self.handle_error(str(e))

    def on_thread_finished(self):
        """线程完成回调"""
        if self.process_thread:
            self.process_thread.wait()
            self.process_thread = None
            QMessageBox.information(self, "处理完成", "所有图片已处理完成！")

    def closeEvent(self, event):
        """窗口关闭事件"""
        # 确保线程正确停止
        if self.process_thread and self.process_thread.isRunning():
            self.process_thread.stop()
            self.process_thread.wait()
            self.process_thread = None
        event.accept()


if __name__ == "__main__":
    app = QApplication(sys.argv)
    window = MilitaryDetectionSystem()
    window.show()
    sys.exit(app.exec_())